<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/model/DAO/PersonDAO.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Entity.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Person.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Role.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/model/Service/Service.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/const/Roles.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/exceptions/DataBaseException.php';

class PersonDAOImpl extends PersonDAO {

	public function create(Entity $person) {
		/*		$sql = 'INSERT INTO `person` (`login`,`password`,`surname`,`name`';
		 if($person->getPatronymic() !== null) {
				$sql .= ',`patronymic`';
				}
				$sql .= ') ';
		$sql .= 'VALUES ("'.$person->getLogin().'"';
				$sql .= ',"'.Roles::getDefaultPassword().'"';
				$sql .= ',"'.$person->getSurname().'"';
				$sql .= ',"'.$person->getName().'"';
				if($person->getPatronymic() !== null) {
				$sql .= ',"'.$person->getPatronymic().'"';
				}
				$sql .= ')';
		try {
		$this->query($sql);
		$person->setIdentity($this->identity());
		return $person;
		} catch(DataBaseException $excepton) {
		return null;
		}
		*/
		$login = $person->getLogin();
		$password = Roles::getDefaultPassword();
		$surname = $person->getSurname();
		$name = $person->getName();
		$patronymic = $person->getPatronymic();

		$sql = 'INSERT INTO `person` (`login`, `password`, `surname`, `name`) VALUES (?, ?, ?, ?)';
		if ($patronymic !== null) {
			$sql = 'INSERT INTO `person`` (login`, `password`, `surname`, `name`, `patronymic`) VALUES (?, ?, ?, ?, ?)';
		}
		$stmt = $this->dbh->connection->prepare($sql);
		$stmt->bindValue(1, $login);
		$stmt->bindValue(2, $password);
		$stmt->bindValue(3, $surname);
		$stmt->bindValue(4, $name);
		if ($patronymic !== null) {
			$stmt->bindValue(5, $patronymic);
		}

		try {
			$this->dbh->query($stmt);
			$person->setIdentity($this->dbh->identity());
			return $person;
		} catch (PDOException $exception) {
			return null;
		}

	}

	// заполняет массив $roles экземпляра класса Person
	public function fillRoles(Person $person) {
		/*		$sql = 'SELECT `role`.`id`, `role`.`name` ';
		 $sql .= 'FROM `permission` INNER JOIN `role` ON `permission`.`id_role`=`role`.`id` ';
		$sql .= 'WHERE `permission`.`id_person`='.$person->getIdentity();
		$this->query($sql);
		while($row = $this->row()) {
		$role = new Role();
		$role->setIdentity($row['id']);
		$role->setName($row['name']);
		$person->addRole($role);
		}
		//Запрос возвращает количество подразделений, которыми руководот сотрудник
		$sql = 'SELECT count(id_employee) FROM `employee` INNER JOIN `department` ON department.id_employee=employee.id where id_person='.$person->getIdentity();
		$this->query($sql);
		$row=$this->row();
		if ($row['count(id_employee)']!=0){
		$role = new Role();
		$role->setIdentity(Roles::DEPARTMENT_HEAD_ROLE);
		$role->setName("руководитель структурного подразделения");
		$person->addRole($role);
		}
		$this->close();
		*/

		$id = $person->getIdentity();
		$sql = 'SELECT `role`.`id`, `role`.`name`';
		$sql .= 'FROM `permission` INNER JOIN `role` ON `permission`.`id_role`=`role`.`id`';
		$sql .= 'WHERE `permission`.`id_person`=?';
		$stmt = $this->dbh->connection->prepare($sql);
		$stmt->bindValue(1, $id);
		$this->dbh->query($stmt);
		while($row = $this->dbh->row()) {
			$role = new Role();
			$role->setIdentity($row['id']);
			$role->setName($row['name']);
			$person->addRole($role);
		}
		$this->dbh->close();
		//Запрос возвращает количество подразделений, которыми руководот сотрудник
		$sql = 'SELECT count(id_employee) FROM `employee` INNER JOIN `department`';
		$sql .= 'ON `department`.`id_employee`=`employee`.`id` WHERE `id_person`=?';
		$stmt = $this->dbh->connection->prepare($sql);
		$stmt->bindValue(1, $id);
		$this->dbh->query($stmt);
		$row=$this->dbh->row();
		if ($row['count(id_employee)']!=0) {
			$role = new Role();
			$role->setIdentity(Roles::DEPARTMENT_HEAD_ROLE);
			$role->setName("руководитель структурного подразделения");
			$person->addRole($role);
		}
		$this->dbh->close();
	}

	/**
	 * Создает массив экземпляров класса Person на основе SQL-запроса
	 * @param unknown $condition Условие выбора
	 * @param unknown $params Параметры выбора
	 * @return multitype:Person Массив экземпляров класса Person
	 */
	private function build($condition,$params) {
		/*		$sql = 'SELECT `id`,`login`,`password`,`surname`,`name`,`patronymic` ';
		 $sql .= 'FROM `person`';
		if($condition !== null) {
		$sql .= ' WHERE '.$condition;
		}
		$this->query($sql);
		$persons = array();
		while($row = $this->row()) {
		$person = new Person();
		$person->setIdentity($row['id']);
		$person->setLogin($row['login']);
		$person->setPassword($row['password']);
		$person->setSurname($row['surname']);
		$person->setName($row['name']);
		$person->setPatronymic($row['patronymic']);
		$persons[] = $person;
		}
		$this->close();
		$service = getService('EmployeeService');
		foreach($persons as $person) {
		$posts = $service->getPersonPosts($person);
		foreach($posts as $post) {
		$person->addPost($post);
		}
		$this->fillRoles($person);
		}
		return $persons;
		*/
		$sql = 'SELECT `id`, `login`, `password`, `surname`, `name`, `patronymic` FROM `person`';
		if($condition !== null) {
			$sql .= ' WHERE '.$condition;
			$stmt = $this->dbh->connection->prepare($sql);
			echo " ";
			var_dump($stmt);
			foreach ($params as $i => $value) {
				$stmt->bindValue($i, $value);//
			}
			echo " ";
			var_dump($stmt);
			$this->dbh->query($stmt);
		}else{
			$this->dbh->execute($sql);
		}

		$persons = array();

		while($row = $this->dbh->row()) {
			$person = new Person();
			$person->setIdentity($row['id']);
			$person->setLogin($row['login']);
			$person->setPassword($row['password']);
			$person->setSurname($row['surname']);
			$person->setName($row['name']);
			$person->setPatronymic($row['patronymic']);
			$persons[] = $person;
		}
		//$this->dbh->close();

		// 		// удалить потом это!!!
		// 		$serviceFactoy = new ServiceFactory(); // Создаем фабрику сервисов
		// 		$service = $serviceFactoy->getService('EmployeeService');// Получаем нужный сервис
		// 		// это раскомментить, это исходное!!!
		// 		//$service = getService('EmployeeService');
		// 		foreach($persons as $person) {
		// 			$posts = $service->getPersonPosts($person);
		// 			foreach($posts as $post) {
		// 				$person->addPost($post);
		// 			}
		// 			$this->fillRoles($person);
		// 		}
		return $persons;
		}

		public function authorization($login, $password) {
			/*		$persons = $this->build('`login`="'.$login.'" AND `password`="'.$password.'"');
			 if(count($persons) == 1) {
			return $persons[0];
			} else {
			return null;
			}
			*/
			$params = array("1"=>$login,"2"=>$password);

			//$stmt = $this->dbh->connection->prepare('login=? AND password=?');
			//$stmt->bindParam(1, $login);
			//$stmt->bindParam(2, $password);

			$persons = $this->build("`login`=? AND `password`=?",$params);
			if(count($persons) == 1) {
				return $persons[0];
			} else {
				return null;
			}
		}

		public function read($identity) {
			/*		$persons = $this->build('`id`='.((int)$identity));
			 if(count($persons) == 1) {
			return $persons[0];
			} else {
			return null;
			}
			*/
			$id = ((int)$identity);
			$params = array("1"=>$id);

			$persons = $this->build('`id`=?',$params);
			if(count($persons) == 1) {
				return $persons[0];
			} else {
				return null;
			}
		}

		public function update(Entity $person) {
			/*		$sql = 'UPDATE `person` ';
			 $sql .= 'SET `login`="'.$person->getLogin().'",';
			$sql .= '`surname`="'.$person->getSurname().'",';
			$sql .= '`name`="'.$person->getName().'"';
			if($person->getPatronymic() !== null) {
			$sql .= ',`patronymic`="'.$person->getPatronymic().'"';
			}
			$sql .= ' WHERE `id`='.$person->getIdentity();
			try {
			$this->query($sql);
			return $person;
			} catch(DataBaseException $excepton) {
			return null;
			}
			*/

			$sql = 'UPDATE `person` SET `login`=:login, `surname`=:surname, `name`=:name';
			if ($patronymic !== null) {
				$sql .= ', `patronymic`=:patronymic';
			}
			$sql .=' WHERE `id`=:id';
				
			$stmt = $this->dbh->connection->prepare($sql);
			$stmt->bindValue(":login", $person->getLogin());
			$stmt->bindValue(":surname", $person->getSurname());
			$stmt->bindValue(":name", $person->getName());
			if ($patronymic !== null) {
				$stmt->bindValue(":partonymic", $person->getPatronymic());
			}
			$stmt->bindValue(":id", $person->getIdentity());

			try {
				$this->dbh->query($stmt);
				return $person;
			} catch (PDOException $exception) {
				return null;
			}
		}

		public function delete($identity) {
			/*		$sql = 'DELETE FROM `person` ';
			 $sql .= 'WHERE `id`='.((int)$identity);
			$this->query($sql);
			return true;
			*/
			$id = (int)($identity);

			$stmt = $this->dbh->connection->prepare('DELETE FROM `person` WHERE `id`=?');
			$stmt->bindValue(1, $id);

			try {
				$this->dbh->query($stmt);
				return true;
			} catch (PDOException $exception) {
				return false;
			}

		}

		public function getAll() {
			return $this->build(null,null);
		}

		public function getRoles() {
			/*		$sql = 'SELECT `id`,`name` ';
			 $sql .= 'FROM `role`';
			$this->query($sql);
			$roles = array();
			while($row = $this->row()) {
			$role = new Role();
			$role->setIdentity($row['id']);
			$role->setName($row['name']);
			$roles[] = $role;
			}
			$this->close();
			return $roles;
			*/

			$stmt = $this->dbh->connection->prepare('SELECT `id`, `name` FROM `role`');
			$this->dbh->query($stmt);

			$roles = array();
			while($row = $this->dbh->row()) {
				$role = new Role();
				$role->setIdentity($row['id']);
				$role->setName($row['name']);
				$roles[] = $role;
			}
			$this->dbh->close();
			return $roles;
		}

		public function changePassword(Person $person) {
			/*		$sql = 'UPDATE `person` ';
			 $sql .= 'SET `password`="'.$person->getPassword().'" ';
			$sql .= 'WHERE `id`='.$person->getIdentity();
			$this->query($sql);
			*/

			$password = $person->getPassword();
			$id = $person->getIdentity();

			$stmt = $this->dbh->connection->prepare('UPDATE `person` SET `password`=? WHERE `id`=?');
			$stmt->bindValue(1, $password);
			$stmt->bindValue(2, $id);
			$this->dbh->query($stmt);
		}

		public function switchRole($personIdentity, $roleIdentity) {
			/*		$sql = 'SELECT `id` ';
			 $sql .= 'FROM `permission` ';
			$sql .= 'WHERE `id_person`='.((int)$personIdentity);
			$sql .= ' AND `id_role`='.((int)$roleIdentity);
			$this->query($sql);
			if($row = $this->row()) {
			$identity = $row['id'];
			} else {
			$identity = null;
			}
			$this->close();
			if($identity !== null) {
			$sql = 'DELETE FROM `permission` ';
			$sql .= 'WHERE `id`='.$identity;
			$this->query($sql);
			} else {
			$sql = 'INSERT INTO `permission` (`id_person`,`id_role`) ';
			$sql .= 'VALUES ('.((int)$personIdentity);
					$sql .= ','.((int)$roleIdentity).')';
			$this->query($sql);
			}
			*/
			$personId = ((int)$personIdentity);
			$roleId = ((int)$roleIdentity);

			$stmt = $this->dbh->connection->prepare('SELECT `id` FROM `permission` WHERE `id_person`=? AND `id_role`=?');
			$stmt->bindValue(1, $personId);
			$stmt->bindValue(2, $roleId);
			$this->dbh->query($stmt);

			if($row = $this->dbh->row()) {
				$identity = $row['id'];
			} else {
				$identity = null;
			}

			$this->dbh->close();

			if($identity !== null) {
				$stmt = $this->dbh->connection->prepare('DELETE FROM `permission` WHERE `id`=?');
				$stmt->bindValue(1, $identity);
				$this->dbh->query($stmt);
			} else {
				$stmt = $this->dbh->connection->prepare('INSERT INTO `permission` (`id_person`, `id_role`) VALUES (?, ?)');
				$stmt->bindValue(1, $personId);
				$stmt->bindValue(2, $roleId);
				$this->dbh->query($stmt);
			}

		}
	}
	?>